package org.dyndns.anderlin.jmplayer.client.ui.binder;

import org.dyndns.anderlin.jmplayer.model.Artist;
import org.dyndns.anderlin.jmplayer.service.ArtistService;
import org.springframework.richclient.util.PopupMenuMouseListener;
import org.springframework.richclient.selection.dialog.ListSelectionDialog;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.util.HashSet;
import java.util.Set;


/**
 * Used by binders
 */
public class ArtistListComponent extends JPanel implements ListSelectionListener {

    private DefaultListModel listModel;
    private JList list;

    private ArtistService artistService;

    private DeleteAction deleteAction;
    private AddAction addAction;

    public ArtistListComponent(ArtistService artistService) {
        this.artistService = artistService;
        listModel = new DefaultListModel();
        list = new JList(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.addListSelectionListener(this);
        deleteAction = new DeleteAction();
        addAction = new AddAction();
        list.addMouseListener(new PopupMenuMouseListener() {
            protected JPopupMenu getPopupMenu() {
                return createSaveFilePopupMenu();
            }
        });
        add(new JScrollPane(list));
        add(new JButton(addAction));
        add(new JButton(deleteAction));

        // disabled before any selection is made:
        deleteAction.setEnabled(false);
    }

    public void setArtists(Set<Artist> artists) {
        listModel.clear();
        if (artists != null) {
            for (Artist a : artists) {
                listModel.addElement(a);
            }
        }
    }

    public Set<Artist> getArtists() {
        Set<Artist> set = new HashSet<Artist>();
        for (Object o : listModel.toArray()) {
            set.add((Artist) o);
        }
        return set;
    }

    private Artist getSelectedArtist() {
        if (list.isSelectionEmpty()) {
            return null;
        }
        return (Artist) listModel.getElementAt(list.getSelectedIndex());
    }

    private void addArtist(Artist artist) {
        if (listModel.contains(artist)) {
            return;
        }
        Set<Artist> oldList = getArtists();
        listModel.addElement(artist);
        firePropertyChange("value", oldList, getArtists());
    }

    private void removeArtist(Artist artist) {
        if (!listModel.contains(artist)) {
            return;
        }
        Set<Artist> oldList = getArtists();
        listModel.removeElement(artist);
        firePropertyChange("value", oldList, getArtists());
    }

    private JPopupMenu createSaveFilePopupMenu() {
        JPopupMenu popupMenu = new JPopupMenu();
        popupMenu.add(deleteAction);
        popupMenu.add(addAction);
        return popupMenu;
    }

    public void setEnabled(boolean enabled) {
        deleteAction.setEnabled(enabled);
    }

    public void valueChanged(ListSelectionEvent listSelectionEvent) {
        deleteAction.setEnabled(!list.isSelectionEmpty());
    }

    private class DeleteAction extends AbstractAction {

        public DeleteAction() {
            // TODO use resource bundle
            this.putValue(Action.NAME, "Delete");
        }

        public void actionPerformed(ActionEvent actionEvent) {
            removeArtist(getSelectedArtist());
        }

    }

    private class AddAction extends AbstractAction {

        public AddAction() {
            // TODO use resource bundle
            this.putValue(Action.NAME, "Add...");
        }

        public void actionPerformed(ActionEvent actionEvent) {

            ListSelectionDialog dialog = new ListSelectionDialog("Select Artist", null, artistService.getAllArtists()) {

                protected void onSelect(Object selection) {
                    addArtist((Artist) selection);
                }
            };
            dialog.showDialog();
        }

    }

}